<?php

namespace App\Services\Sms;

use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
use App\Models\Common\EmailLog;
use App\Models\Common\SmsLog;
use App\Services\Com\EmailService;
use App\Services\Com\EnvSmsService;
use App\Services\Com\LogService;
use App\Services\Com\StudySmsService;
use Darabonba\OpenApi\Models\Config;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Mail;
use Qcloud\Sms\SmsSingleSender;

class CaptchaService
{
    /**
     * 使用AK&SK初始化账号Client
     * @param string $accessKeyId
     * @param string $accessKeySecret
     * @return Dysmsapi Client
     */
    public static function createClient(){
        $config = new Config([
            // 您的AccessKey ID
            "accessKeyId" => config('sms.accessKeyId'),
            // 您的AccessKey Secret
            "accessKeySecret" => config('sms.accessKeySecret')
        ]);
        // 访问的域名
        $config->endpoint = "dysmsapi.aliyuncs.com";
        return new Dysmsapi($config);
    }

    /**
     * 发送验证码
     * @param $to  type=1 为手机号码 =2为邮箱
     * @param $code
     * @param $templateCode
     * @param int $type  1短信发送 2邮箱发送
     * @return bool
     * @throws \Exception
     */
    public static function sendCode(string $to, string $code, string $templateCode='', int $type=1)
    {
        // 发送验证码
        try
        {
            switch ($type){
                case 1:
                    if(in_array($to, config('sms.test_phone')) || substr($to, 0, strlen('86112')) == '86112'){
                        return true;
                    }
                    $client = self::createClient();
                    $sendSmsRequest = new SendSmsRequest([
                        "phoneNumbers" => $to,
                        "signName" => config('sms.sign_name.migo'),
                        "templateCode" => $templateCode,
                        "templateParam" => json_encode(['code'=>$code]),
                    ]);
                    $result = $client->sendSms($sendSmsRequest)->body;

                    SmsLog::create([
                        'mobile' => $to,
                        'param' => json_encode(['code'=>$code]),
                        'template_code' => $templateCode,
                        'result_code' => $result->code,
                        'result_msg' => isset($result->message) ? '' : $result->message,
                    ]);

                    if($result->code != 'OK') throw new \Exception($result->message);

                    break;
                case 2:
                    $message_text = "【MIGO】您的验证码为：{$code}";
                    EmailService::send($to, $message_text, [], '验证码', 1, $templateCode);
//                    Mail::raw($message_text, function ($message) use($to){
//                        $message->subject('MIGO');
//                        $message->to($to);
//                    });
//
//                    EmailLog::create([
//                        'email' => $to,
//                        'param' => $message_text,
//                        'template_code' => $templateCode,
//                        'result_code' => count(Mail::failures()) >= 1 ? 'fail' : 'success',
//                    ]);
//
//                    if(count(Mail::failures()) >= 1) throw new \Exception('验证码发送失败！');

                    break;
                case 3:
                    $result = StudySmsService::mobileSMS7(['mobile'=>substr($to, 2),'content'=>"您的验证码为：{$code}"]);

                    SmsLog::create([
                        'mobile' => $to,
                        'param' => json_encode(['code'=>$code]),
                        'template_code' => $templateCode,
                    ]);

                    if(!$result) throw new \Exception('发送失败');
                    break;
                case 4:
                    $param = [
                        'phone' => $to,
                        'content' => "【山南环保】您的手机验证码为{$code},10分钟内有效，若非本人操作，请忽略，谢谢。",
                    ];
                    $result = EnvSmsService::send([$param]);

                    SmsLog::create([
                        'mobile' => $to,
                        'param' => json_encode(['code'=>$code]),
                        'template_code' => $templateCode,
                    ]);

                    if(!$result) throw new \Exception('发送失败');
                    break;
                default:
                    throw new \Exception('发送验证码异常');
                    break;
            }

        }
        catch (\Exception $e)
        {
            LogService::error('Sms Error: '.$e->getMessage());

            throw new \Exception($e->getMessage());
        }

        // 写入缓存
        Cache::put("sms_captcha_{$to}", md5($code), config('sms.captcha.expiring'));
        Cache::put("sms_captcha_interval_{$to}", md5($code), config('sms.captcha.SMS_TTL'));

        return true;
    }

    //普通短信
    public static function send($mobile, $templateCode, $templateParam=[])
    {
        try
        {
            $client = self::createClient();
            $sendSmsRequest = new SendSmsRequest([
                "phoneNumbers" => $mobile,
                "signName" => config('sms.sign_name.migo'),
                "templateCode" => $templateCode,
                "templateParam" => json_encode($templateParam),
            ]);
            $result = $client->sendSms($sendSmsRequest)->body;

            if($result->code != 'OK') throw new \Exception($result->message);
        }
        catch (\Exception $e)
        {
            LogService::error('Sms Error: '.$e->getMessage());

            throw new \Exception($e->getMessage());
        }

        return true;
    }

    /**
     * 验证短信验证码
     *
     * @param $mobile
     * @param $code
     *
     * @return bool
     */
    public static function verify($mobile, $code)
    {
        // 验证手机号
//        if (11 !== strlen($mobile) || !preg_match('#^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^17[0,6,3,7,8]{1}\d{8}$|^18[\d]{9}$|^19[\d]{9}$#', $mobile))
//        {
//            throw new \Exception('手机号码错误');
//        }

        // 验证验证码
        if(4 !== strlen($code)) throw new \Exception('验证码格式错误');
        if(!Cache::has("sms_captcha_{$mobile}")) throw new \Exception('验证码错误');

        if (md5($code) !== Cache::get("sms_captcha_{$mobile}"))throw new \Exception('验证码错误');

        // 清除缓存
        Cache::forget("sms_captcha_{$mobile}");
        Cache::forget("sms_captcha_interval_{$mobile}");

        return true;
    }

    /**
     * 是否拥有有效短信验证码
     *
     * @param $mobile
     *
     * @return bool
     */
    public static function has($mobile)
    {
        return Cache::has("sms_captcha_interval_{$mobile}");
    }
}
